package tree.huffmanCoding;

import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.HashMap;
import java.util.Map;

/**
 * 创建节点类，为了让Node对象支持排序  实现Comparable接口
 * ch对应的权重为weight
 */
@Data
@NoArgsConstructor
public class CharNode implements Comparable<CharNode> {
    private Byte data;    // 字符
    private int weight; // 权重
    private CharNode left;
    private CharNode right;

    /**
     * important!!!!!important
     */
    // 1.将霍夫曼编码存放在Map<Byte,String>形式
    private static Map<Byte, String> huffmanCodes = new HashMap<>();



    public CharNode(int weight) {
        this.weight = weight;
    }

    public CharNode(Byte ch, int weight) {
        this.data = ch;
        this.weight = weight;
    }

    @Override
    public String toString() {
        return "Node{" +
                "ch=" + data +
                ", weight=" + weight +
                '}';
    }

    // 前序遍历
    public void preOrder() {
        System.out.print(weight + ",");
        if (null != left) {
            left.preOrder();
        }
        if (null != right) {
            right.preOrder();
        }
    }

    /**
     * 生成霍夫曼树对应的霍夫曼编码才是灵魂
     * 如何拼接"0" 和 "1" 太nb了
     *  🌟🌟🌟🌟🌟
     *  🌟🌟🌟🌟🌟
     *   🌟🌟🌟🌟🌟
     */
    public Map<Byte, String> getCharCodingAtHuffmanTree(CharNode node, String code, StringBuilder stringBuilder) {
        //2. 在生成霍夫曼编码表示，需要去拼接路径,定义一个StringBuilder 存储某个叶子节点的路径
        StringBuilder stringBuilderNew = new StringBuilder(stringBuilder);
        stringBuilderNew.append(code);
        if (node != null) {
            if (node.data == null) { // 我们在生成霍夫曼树的时候将非叶子节点设置成了Null
                getCharCodingAtHuffmanTree(node.left, "0", stringBuilderNew);
                getCharCodingAtHuffmanTree(node.right, "1", stringBuilderNew);
            } else {
                // 说明这是某个叶子节点的最后
                huffmanCodes.put(node.getData(), stringBuilderNew.toString());
            }
        }
        return huffmanCodes;
    }

    @Override
    public int compareTo(CharNode o) {
        return weight - o.getWeight();
    }
}